/**
 * 战斗状态管理器
 * 负责管理战斗过程中的状态变化和数据同步
 */

import { BattleState, BattlePhase, BattleStatus, BattleParticipant, BattleContext } from './types';
import { ServiceLogger } from '../../../infrastructure/logging/UnifiedLogger';

/**
 * 状态变化事件
 */
export interface StateChangeEvent {
    battleId: string;
    previousState: Partial<BattleState>;
    newState: Partial<BattleState>;
    changeType: 'phase' | 'status' | 'round' | 'participant' | 'general';
    timestamp: number;
}

/**
 * 战斗状态管理器
 */
export class BattleStateManager {
    private logger: ServiceLogger;
    private stateHistory = new Map<string, BattleState[]>();
    private maxHistorySize = 50; // 保留最近50个状态

    constructor() {
        this.logger = new ServiceLogger('BattleStateManager');
    }

    /**
     * 更新战斗阶段
     */
    updatePhase(context: BattleContext, newPhase: BattlePhase): BattleContext {
        const previousPhase = context.state.phase;
        
        if (previousPhase === newPhase) {
            return context; // 无变化
        }

        this.logger.debug(`Battle phase transition: ${previousPhase} -> ${newPhase}`, {
            metadata: { battleId: context.state.battleId }
        });

        // 验证阶段转换的有效性
        if (!this.isValidPhaseTransition(previousPhase, newPhase)) {
            this.logger.warn(`Invalid phase transition: ${previousPhase} -> ${newPhase}`, {
                metadata: { battleId: context.state.battleId }
            });
        }

        // 创建新状态
        const newState = {
            ...context.state,
            phase: newPhase
        };

        // 保存状态历史
        this.saveStateToHistory(context.state.battleId, context.state);

        // 更新上下文
        const updatedContext = {
            ...context,
            state: newState
        };

        this.logger.info(`Battle phase updated: ${newPhase}`, {
            metadata: { 
                battleId: context.state.battleId,
                previousPhase,
                currentRound: newState.currentRound
            }
        });

        return updatedContext;
    }

    /**
     * 更新战斗状态
     */
    updateStatus(context: BattleContext, newStatus: BattleStatus): BattleContext {
        const previousStatus = context.state.status;
        
        if (previousStatus === newStatus) {
            return context; // 无变化
        }

        this.logger.debug(`Battle status transition: ${previousStatus} -> ${newStatus}`, {
            metadata: { battleId: context.state.battleId }
        });

        const newState = {
            ...context.state,
            status: newStatus
        };

        // 如果状态变为完成或取消，设置结束时间
        if (newStatus === BattleStatus.COMPLETED || newStatus === BattleStatus.CANCELLED || newStatus === BattleStatus.ERROR) {
            newState.endTime = Date.now();
        }

        this.saveStateToHistory(context.state.battleId, context.state);

        const updatedContext = {
            ...context,
            state: newState
        };

        this.logger.info(`Battle status updated: ${newStatus}`, {
            metadata: { 
                battleId: context.state.battleId,
                previousStatus,
                endTime: newState.endTime
            }
        });

        return updatedContext;
    }

    /**
     * 推进到下一回合
     */
    advanceRound(context: BattleContext): BattleContext {
        const newRound = context.state.currentRound + 1;
        
        this.logger.debug(`Advancing to round ${newRound}`, {
            metadata: { battleId: context.state.battleId }
        });

        const newState = {
            ...context.state,
            currentRound: newRound
        };

        this.saveStateToHistory(context.state.battleId, context.state);

        const updatedContext = {
            ...context,
            state: newState
        };

        this.logger.info(`Round advanced to ${newRound}`, {
            metadata: { 
                battleId: context.state.battleId,
                maxRounds: context.state.maxRounds
            }
        });

        return updatedContext;
    }

    /**
     * 更新参与者状态
     */
    updateParticipant(context: BattleContext, participantId: string, updates: Partial<BattleParticipant>): BattleContext {
        const updateParticipants = (participants: BattleParticipant[]): BattleParticipant[] => {
            return participants.map(participant => 
                participant.id === participantId 
                    ? { ...participant, ...updates }
                    : participant
            );
        };

        const newState = {
            ...context.state,
            homeParticipants: updateParticipants(context.state.homeParticipants),
            awayParticipants: updateParticipants(context.state.awayParticipants)
        };

        this.saveStateToHistory(context.state.battleId, context.state);

        const updatedContext = {
            ...context,
            state: newState
        };

        this.logger.debug(`Participant updated: ${participantId}`, {
            metadata: { 
                battleId: context.state.battleId,
                updates: Object.keys(updates)
            }
        });

        return updatedContext;
    }

    /**
     * 设置当前行动者
     */
    setCurrentActor(context: BattleContext, actorId: string | undefined): BattleContext {
        const newState = {
            ...context.state,
            currentActor: actorId
        };

        const updatedContext = {
            ...context,
            state: newState
        };

        this.logger.debug(`Current actor set: ${actorId || 'none'}`, {
            metadata: { battleId: context.state.battleId }
        });

        return updatedContext;
    }

    /**
     * 获取参与者
     */
    getParticipant(context: BattleContext, participantId: string): BattleParticipant | undefined {
        const allParticipants = [...context.state.homeParticipants, ...context.state.awayParticipants];
        return allParticipants.find(p => p.id === participantId);
    }

    /**
     * 获取存活的参与者
     */
    getAliveParticipants(context: BattleContext, isHome?: boolean): BattleParticipant[] {
        let participants: BattleParticipant[];
        
        if (isHome === true) {
            participants = context.state.homeParticipants;
        } else if (isHome === false) {
            participants = context.state.awayParticipants;
        } else {
            participants = [...context.state.homeParticipants, ...context.state.awayParticipants];
        }

        return participants.filter(p => p.isAlive);
    }

    /**
     * 检查战斗是否结束
     */
    isBattleOver(context: BattleContext): boolean {
        const aliveHome = this.getAliveParticipants(context, true);
        const aliveAway = this.getAliveParticipants(context, false);
        
        // 一方全部死亡
        if (aliveHome.length === 0 || aliveAway.length === 0) {
            return true;
        }
        
        // 达到最大回合数
        if (context.state.currentRound >= context.state.maxRounds) {
            return true;
        }
        
        // 状态已经是完成
        if (context.state.status === BattleStatus.COMPLETED || 
            context.state.status === BattleStatus.CANCELLED ||
            context.state.status === BattleStatus.ERROR) {
            return true;
        }
        
        return false;
    }

    /**
     * 获取获胜方
     */
    getWinner(context: BattleContext): 'home' | 'away' | 'draw' | null {
        if (!this.isBattleOver(context)) {
            return null;
        }

        const aliveHome = this.getAliveParticipants(context, true);
        const aliveAway = this.getAliveParticipants(context, false);

        if (aliveHome.length > 0 && aliveAway.length === 0) {
            return 'home';
        } else if (aliveAway.length > 0 && aliveHome.length === 0) {
            return 'away';
        } else {
            return 'draw';
        }
    }

    /**
     * 获取状态历史
     */
    getStateHistory(battleId: string): BattleState[] {
        return this.stateHistory.get(battleId) || [];
    }

    /**
     * 清理状态历史
     */
    clearStateHistory(battleId: string): void {
        this.stateHistory.delete(battleId);
        this.logger.debug(`State history cleared for battle: ${battleId}`);
    }

    /**
     * 创建状态快照
     */
    createSnapshot(context: BattleContext): BattleState {
        return JSON.parse(JSON.stringify(context.state));
    }

    /**
     * 验证状态完整性
     */
    validateState(context: BattleContext): boolean {
        const state = context.state;
        
        // 基本字段检查
        if (!state.battleId || !state.phase || !state.status) {
            this.logger.error('Invalid state: missing required fields', {
                metadata: { battleId: state.battleId || 'unknown' }
            });
            return false;
        }

        // 参与者检查
        if (state.homeParticipants.length === 0 && state.awayParticipants.length === 0) {
            this.logger.error('Invalid state: no participants', {
                metadata: { battleId: state.battleId }
            });
            return false;
        }

        // 回合数检查
        if (state.currentRound < 0 || state.currentRound > state.maxRounds) {
            this.logger.error('Invalid state: round out of bounds', {
                metadata: { 
                    battleId: state.battleId,
                    currentRound: state.currentRound,
                    maxRounds: state.maxRounds
                }
            });
            return false;
        }

        return true;
    }

    /**
     * 重置战斗状态到初始状态
     */
    resetToInitialState(context: BattleContext): BattleContext {
        const newState = {
            ...context.state,
            phase: BattlePhase.PREPARING,
            status: BattleStatus.PENDING,
            currentRound: 0,
            currentActor: undefined,
            endTime: undefined
        };

        // 重置所有参与者状态
        const resetParticipants = (participants: BattleParticipant[]): BattleParticipant[] => {
            return participants.map(p => ({
                ...p,
                isAlive: !p.component.isDie()
            }));
        };

        newState.homeParticipants = resetParticipants(newState.homeParticipants);
        newState.awayParticipants = resetParticipants(newState.awayParticipants);

        const updatedContext = {
            ...context,
            state: newState,
            eventHistory: [],
            logs: [],
            temporaryData: new Map()
        };

        this.logger.info(`Battle state reset to initial state`, {
            metadata: { battleId: context.state.battleId }
        });

        return updatedContext;
    }

    // ==================== 私有方法 ====================

    /**
     * 验证阶段转换的有效性
     */
    private isValidPhaseTransition(from: BattlePhase, to: BattlePhase): boolean {
        const validTransitions: Record<BattlePhase, BattlePhase[]> = {
            [BattlePhase.PREPARING]: [BattlePhase.INITIALIZING],
            [BattlePhase.INITIALIZING]: [BattlePhase.ROUND_START, BattlePhase.BATTLE_END],
            [BattlePhase.ROUND_START]: [BattlePhase.UNIT_ACTION, BattlePhase.BATTLE_END],
            [BattlePhase.UNIT_ACTION]: [BattlePhase.ROUND_END, BattlePhase.UNIT_ACTION, BattlePhase.BATTLE_END],
            [BattlePhase.ROUND_END]: [BattlePhase.ROUND_START, BattlePhase.BATTLE_END],
            [BattlePhase.BATTLE_END]: [BattlePhase.COMPLETED],
            [BattlePhase.COMPLETED]: []
        };

        return validTransitions[from]?.includes(to) || false;
    }

    /**
     * 保存状态到历史记录
     */
    private saveStateToHistory(battleId: string, state: BattleState): void {
        let history = this.stateHistory.get(battleId);
        if (!history) {
            history = [];
            this.stateHistory.set(battleId, history);
        }

        // 创建状态副本
        const stateCopy = JSON.parse(JSON.stringify(state));
        history.push(stateCopy);

        // 限制历史记录大小
        if (history.length > this.maxHistorySize) {
            history.shift();
        }
    }
}
